/*
 * CommandThread.cpp
 *
 *  Created on: 2016年3月18日
 *      Author: terry
 */

#include "CommandThread.h"

namespace util
{


Param::Param():
	type(kInt),
	value()
{
}

Param::Param(bool value):
		type(kBool)
{
	this->value.b = value;
}

Param::Param(int32_t value):
		type(kInt)
{
	this->value.i32 = value;
}

Param::Param(int64_t value):
				type(kLong)
{
	this->value.i64 = value;
}

Param::Param(float value):
		type(kFloat)
{
	this->value.f = value;
}

Param::Param(double value):
				type(kDouble)
{
	this->value.d = value;
}

Param::Param(const char* value):
				type(kString)
{
	str = value;
}

Param::Param(const std::string& value):
				type(kString)
{
	str = value;
}

Param::Param(void* value):
				type(kPointer)
{
	this->value.ptr = value;
}

bool Param::toBool() const
{
	return value.b;
}

int  Param::toInt() const
{
	return value.i32;
}

int64_t Param::toLong() const
{
	return value.i64;
}

float Param::toFloat() const
{
	return value.f;
}

double Param::toDouble() const
{
	return value.d;
}

std::string Param::toString() const
{
	return str;
}

void* Param::toPtr() const
{
	return value.ptr;
}



Param CommandThread::s_param;



CommandThread::CommandThread()
{
}

CommandThread::~CommandThread()
{
}


void CommandThread::postCommand(const Command& cmd)
{
	{
		comn::AutoCritSec lock(m_csCmd);
		m_cmdQueue.push(cmd);
	}
	m_eventCmd.post();
}

void CommandThread::postCommand(int cmdType)
{
	Command cmd(cmdType);
	postCommand(cmd);
}

bool CommandThread::getCommand(Command& cmd)
{
	bool found = false;
	comn::AutoCritSec lock(m_csCmd);
	if (m_cmdQueue.size() > 0)
	{
		cmd = m_cmdQueue.front();
		m_cmdQueue.pop();
		found = true;
	}
	return found;
}

void CommandThread::clearQueue()
{
	comn::AutoCritSec lock(m_csCmd);
    while (m_cmdQueue.size() > 0)
    {
	    m_cmdQueue.pop();
    }
}

void CommandThread::postEvent()
{
	m_eventCmd.post();
}

bool CommandThread::timedwait(int ms)
{
	return m_eventCmd.timedwait(ms);
}

int CommandThread::run()
{
	while (!m_canExit)
	{
		if (!fetchAndHandle())
		{
			onIdle();
		}
	}
	return 0;
}

void CommandThread::doStop()
{
	postEvent();
}

bool CommandThread::fetchAndHandle()
{
	Command cmd;
	if (!getCommand(cmd))
	{
		return false;
	}

	if (cmd.type == kQuit)
	{
		tryStop();
		return false;
	}

	onCommand(cmd);
	return true;
}

void CommandThread::onIdle()
{
	m_eventCmd.timedwait(IDLE_DURATION);
}

void CommandThread::stop()
{
	if (isRunning())
	{
		comn::Thread::stop();
	}

	clearQueue();
}




} /* namespace util */
